package controller.login;

import com.alibaba.fastjson.JSONObject;
import model.User;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import service.UserService;
import service.impl.UserServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.Properties;
import java.util.UUID;

@WebServlet("/wx_login")
public class WxLoginServlet extends HttpServlet {

    private UserService userService = new UserServiceImpl();

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        String code = req.getParameter("code");
        Properties prop = new Properties();
        prop.load(this.getClass().getClassLoader().getResourceAsStream("config.properties"));
        String appid = prop.getProperty("wx.AppID");
        String AppSecret = prop.getProperty("wx.AppSecret");
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + AppSecret +
                "&code=" + code + "&grant_type=authorization_code";

        // 获取AccessToken、openid等数据
        JSONObject authInfo = auth(url);
        System.out.println("authInfo: " + authInfo);

        url = "https://api.weixin.qq.com/sns/userinfo?access_token=" +
                authInfo.getString("access_token") + "&openid=" + authInfo.getString("openid");
        JSONObject userInfo = getUserInfo(url);
        System.out.println("userInfo: " + userInfo);
        // 根据微信的openid查询此用户原来有没有使用过微信登录
        User user = userService.findByWxOpenid(userInfo.getString("openid"));
        if (user == null) {

            user = new User();
            // 用户的头像
            user.setPic(userInfo.getString("headimgurl"));
            // 性别
            user.setGender(userInfo.getString("sex"));
            // 用户的昵称
            user.setRealName(userInfo.getString("nickname"));

            // 随机用户名(11位随机字符串)
            user.setUsername(UUID.randomUUID().toString().substring(36 - 15));

            user.setWxOpenid(userInfo.getString("openid"));
            // 注册一个新的用户
            userService.save(user);

        }

        // 修改登录时间
        user.setLoginTime(new Date());
        userService.update(user);
        session.setAttribute("loginUser", user);
        resp.sendRedirect("/html/home.jsp");
    }

    private JSONObject auth(String url) {
        try {
            // 创建一个http Client请求
            CloseableHttpClient client = HttpClients.createDefault();

            HttpGet httpGet = new HttpGet(url);

            HttpResponse response = client.execute(httpGet);
            HttpEntity entity = response.getEntity();
            // 获取响应数据(json)

            if (entity != null) {
                String result = EntityUtils.toString(entity, Charset.forName("UTF8"));
                return JSONObject.parseObject(result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    private JSONObject getUserInfo(String url) {

        try {
            CloseableHttpClient client = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet(url);
            HttpResponse response = client.execute(httpGet);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String result = EntityUtils.toString(entity, Charset.forName("UTF8"));
                return JSONObject.parseObject(result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
